/**
 * gislin 2017年9月20日
 */
package com.btcode.orm.relation.ex;

import com.btcode.exception.MsgException;
import com.btcode.orm.exception.IllegalJoinException;
import com.btcode.orm.model.IField;
import java.io.Serializable;

/**
 * @author gislin 2017年9月20日
 */
public class Relation implements IRelation, Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    /**
     * 主表和从表关联的字段
     */
    private IField masterField;

    /**
     * 和主表A关联的从表字段
     */
    private IField slaveField;
    /**
     * masterAField 和 slaveAField的关联，成为PrimaryRelation 这个关联是否缓存
     */
    private boolean isPrimaryRelationCache;
    /**
     * 多对多主表的外键字段
     */
    private IField m2mMasterField;

    /**
     * 和多对多主表关联的从表字段，其与slaveField必须是同一张表
     */
    private IField m2mSlaveField;

    /**
     * 是否多对多关联
     */
    private boolean isManyToMany;

    /**
     * 是否级联删除
     */
    private boolean isRelationDelete = false;

    /**
     * @param fkField 本表与从表关联的字段，一般是主键
     * @param slaveField 从表与之关联的键，就是外键
     */
    public Relation(IField masterAField, IField slaveAField, boolean isNeedCache) {
        oneToMany(masterAField, slaveAField, false, isNeedCache);
    }

    /**
     * @param fkField 本表与从表关联的字段，一般是主键
     * @param slaveField 从表与之关联的键，就是外键
     */
    public Relation(IField masterAField, IField slaveAField, boolean isRelationDelete,
        boolean isNeedCache) {
        oneToMany(masterAField, slaveAField, isRelationDelete, isNeedCache);
    }

    public void oneToMany(IField masterAField, IField slaveAField, boolean isRelationDelete,
        boolean isNeedCache) {

        this.masterField = masterAField;
        this.slaveField = slaveAField;
        this.isPrimaryRelationCache = isNeedCache;
        this.isRelationDelete = isRelationDelete;
    }

    public IRelation manyToMany(IField masterBField, IField slaveBField) {

        if (masterField == null || slaveField == null) {
            throw new IllegalJoinException("在oneToMany设置之前，不能进行多对多设置", null);
        }

        if (!slaveBField.getModelClass().equals(slaveField.getModelClass())) {
            throw new IllegalJoinException(
                slaveField.getModelClass() + "和" + slaveField.getModelClass() + "不匹配", null);
        }

        this.m2mMasterField = masterBField;
        this.m2mSlaveField = slaveBField;
        this.isManyToMany = true;
        return this;
    }

    public boolean isPrimaryRelationCache() {
        return isPrimaryRelationCache;
    }

    public boolean isManyToMany() {
        return isManyToMany;
    }

    public IField getMasterField() {
        return masterField;
    }

    public IField getSlaveField() {
        return slaveField;
    }

    public IField getM2mMasterField() {
        if (!isManyToMany) {
            throw new MsgException("该关联非多对多关联，不能进行该操作.");
        }
        return m2mMasterField;
    }

    public IField getM2mSlaveField() {
        if (!isManyToMany) {
            throw new MsgException("该关联非多对多关联，不能进行该操作.");
        }
        return m2mSlaveField;
    }

    @Override
    public boolean isRelationDelete() {
        return isRelationDelete;
    }

}
